home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 9 / Night Owl CD-ROM (NOPV9) (Night Owl Publisher) (1993).ISO / 009a / newtk200.zip / NEWTK200.TXT < prev    next >
Text File  |  1993-03-16  |  36KB  |  1,187 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.             Cavendish Software Ltd
  12.             Memory Allocation Tracking for C++
  13.             NewTrack v2.0
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.             Document Reference: NEWTK200
  23.             Last Printed: 16/03/93 17:18
  24.  
  25.             Revision 1.01 by John Spackman, Tuesday 16th March 1993
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.              Copyright c 1991-1993 Cavendish Software Ltd. All Rights
  66.                                     Reserved.
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.             Table Of Contents
  77.  
  78.  
  79.              Introduction .......................................1
  80.  
  81.              How NewTrack can ease development ..................3
  82.                  Multiple or Invalid Deletions ..................3
  83.                  Pointer Overruns and Underruns .................4
  84.                  Unfreed Memory .................................4
  85.                  Uninitialised Data .............................5
  86.                  Using Deleted Memory ...........................6
  87.                  Out of Memory ..................................6
  88.  
  89.              How to Use NewTrack ................................7
  90.                  Adding NewTrack to the build ...................7
  91.                  Starting and Stopping NewTrack .................7
  92.                  Temporarily Stopping NewTrack ..................8
  93.                  Dialogue Box ...................................9
  94.                  Debugging with NewTrack ........................9
  95.  
  96.              Pitfalls and Programming Considerations ............10
  97.                  Malloc() .......................................10
  98.                  Automatics .....................................10
  99.  
  100.              Porting to other Environments and Compilers ........11
  101.                  Memory Model ...................................11
  102.                  Versions of operator new() .....................11
  103.                  Getting the callers address ....................11
  104.                  Inline assembler ...............................12
  105.                  Shared libraries/DLLs ..........................12
  106.                  User I/O .......................................13
  107.  
  108.              Comments, and where to find us .....................14
  109.  
  110.              Copyright, Use & Copying ...........................16
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.              Copyright c 1991-1993 Cavendish Software Ltd. All Rights
  131.                                     Reserved.
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.             Introduction
  142.  
  143.                    NewTrack is an extension to C++ programs which
  144.                    validates deletes, discovers memory over and
  145.                    underruns, and shows up any unfreed memory
  146.                    allocations.  Written for Borland C++ v3.1 and MS-
  147.                    Windows, NewTrack is a surprisingly small and
  148.                    simple library and DLL combination which can
  149.                    discover many intermittent and unreproducable
  150.                    faults within an application.
  151.  
  152.                    Although Windows is a protected mode environment,
  153.                    you might think that illegal memory access such as
  154.                    that caused by overrunning an allocated block or
  155.                    deleting an invalid pointer would be trapped with
  156.                    a GP Fault.  Not true.  Although Windows apps have
  157.                    a theoretical address space of 64Gb in 386
  158.                    enhanced mode, you can only make 8192 calls to
  159.                    GlobalAlloc().  As a result, the compiler of
  160.                    choice has to allocate much larger "pages" of
  161.                    memory and suballocate them itself when malloc()
  162.                    is called.  If you then overrun your allocation,
  163.                    the chances are you write on other parts of your
  164.                    data, and invalid deletions (ie calls to free())
  165.                    make the compiler quietly disfigure it's own
  166.                    suballocation tables.
  167.  
  168.                    By making a list of all allocations a program
  169.                    makes via calls to new, NewTrack can determine
  170.                    whether this is valid and tell the user.  By
  171.                    allocating extra memory either side of the block
  172.                    requested by new and filling with a known value,
  173.                    NewTrack can detect if the program overran (or
  174.                    underran) the requested block by comparing the
  175.                    additional memory with the known value when it is
  176.                    deleted.
  177.  
  178.                    Another side-effect of the suballocation scheme is
  179.                    that memory remains not only accessible but also
  180.                    has once-sensible values in it.  Immediately
  181.                    before deletion, NewTrack fills the memory with
  182.                    0xFF.  Similarly, when the memory is first
  183.                    allocated the contents are unknown, although often
  184.                    zero.  NewTrack fills the memory with a known non-
  185.                    zero value when allocated, forcing the programmer
  186.                    to explicitly initialise data.
  187.  
  188.                    NewTrack currently only attempts to replace the
  189.                    new and delete calls, because to replace malloc(),
  190.                    farmalloc(), etc would require a private memory
  191.                    suballocation scheme.  As in the standard new and
  192.                    delete functions, memory is allocated and
  193.                    deallocated by using farmalloc() and free()
  194.                    respectively.
  195.  
  196.  
  197.             Cavendish Software Ltd                                1
  198.  
  199.  
  200.  
  201.  
  202.  
  203.                    Please note that NewTrack has only been tested
  204.                    (although very extensively) in Large memory model
  205.                    under Borland C++ v3.0 and 3.1.
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.             Cavendish Software Ltd                                2
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.             How NewTrack can ease development
  274.  
  275.  
  276.  
  277.  
  278.                Multiple or Invalid Deletions
  279.  
  280.                    During the development of any large program, a
  281.                    number of bugs will creep into the code regardless
  282.                    of the best efforts (or BS standards!), and it's
  283.                    not surprising if sometimes a pointer is deleted
  284.                    more than once, or a critical block is not called
  285.                    to initialise a pointer.
  286.  
  287.                    Sometimes this is easy to spot: under Windows an
  288.                    instant GP Fault or "UAE" may occur, because the
  289.                    free() function attempts to write on a header
  290.                    block of memory that is no longer available,
  291.                    allowing a simple and quick solution.  But
  292.                    sometimes that memory will have been already
  293.                    reallocated, and free() will erroneously write on
  294.                    memory and inexplicably corrupt data.  A further
  295.                    problem is that Windows (like all good operating
  296.                    systems) can often corrupt it's own internal data
  297.                    structures, leaving you (or rather, the user) with
  298.                    an unstable system that is likely to crash at
  299.                    anytime, possibly even after your application has
  300.                    terminated cleanly.
  301.  
  302.                    NewTrack will detect and prevent any attempt to
  303.                    delete an invalid pointer (including NULL), by
  304.                    keeping a list of all the allocations which have
  305.                    been made, and checking the pointer against this
  306.                    list.  If the pointer is not in the list, the user
  307.                    will be allowed to continue or abort the program
  308.                    using the dialogue box described below.
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.             Cavendish Software Ltd                                3
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.                Pointer Overruns and
  340.                Underruns                   A not so common pitfall is to overrun or under run
  341.                    a block of memory.  An Overrun is to simply use
  342.                    too much memory, and exceed the allocated block;
  343.                    an underrun is to exceed the limits in the other
  344.                    direction, and use memory in front of the
  345.                    allocated block.  Probably the most common example
  346.                    of an Overrun is allocating a block to hold a copy
  347.                    of a string that is strlen(my_string) long;  when
  348.                    strcpy() is used to copy my_string into the
  349.                    allocated block, it will add a trailing NULL
  350.                    character, overrunning the available space by just
  351.                    1 byte.
  352.  
  353.                    Again, these bugs are sometimes easy to spot in a
  354.                    "protected" environment such as Windows; a GP
  355.                    Fault will occur and you can hopefully still trace
  356.                    it in the debugger.  However, it is quite likely
  357.                    that next time you run the program (eg under the
  358.                    debugger), the Overrun or Underrun writes on
  359.                    memory which you have already allocated and
  360.                    therefore will quietly corrupt memory without
  361.                    telling you.
  362.  
  363.                    NewTrack will detect these bugs by always
  364.                    allocating a small amount (12 bytes) of memory
  365.                    extra to act as headers and footers to the block
  366.                    which you allocate.  It then fills these blocks
  367.                    with a known value, and checks them again when the
  368.                    pointer is deleted.  If a value in the header or
  369.                    footer has changed by the time the pointer is
  370.                    deleted, an Overrun or Underrun has occurred, and
  371.                    the user will be allowed to continue or abort the
  372.                    program using the dialogue box described below.
  373.  
  374.  
  375.  
  376.  
  377.                Unfreed Memory
  378.  
  379.                    A much more frequent and harder bug is failing to
  380.                    free up allocated memory.  This is less noticeable
  381.                    under Windows because of the virtual memory it
  382.                    provides, but still very difficult to track down,
  383.                    as well as to diagnose.  NewTrack was initially
  384.                    developed explicitly to solve this problem during
  385.                    a project that eventually grew to over 2.5Mb of
  386.                    C++ source code before the first release.
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.             Cavendish Software Ltd                                4
  396.  
  397.  
  398.  
  399.  
  400.  
  401.                    Even if you do know that "somewhere" inside 2.5Mb
  402.                    of event-driven code in executables and DLLs,
  403.                    you're losing approximately 2K a minute (for
  404.                    example) or that after running for three days
  405.                    Windows says it's low on memory, this does nothing
  406.                    for the programmer except cause a very big
  407.                    headache.
  408.  
  409.                    When new is called to allocate memory, NewTrack
  410.                    will record the allocation and the address of the
  411.                    code that called it.  This means that, using a
  412.                    debugger, you can set a breakpoint at the
  413.                    hexadecimal address recorded, restart the program,
  414.                    and the debugger will instantly show you where the
  415.                    unfreed allocation was made, often reducing the
  416.                    debugging time from hours or days to minutes.
  417.  
  418.                    At the end of a program when NewTrack is
  419.                    terminated, it will check it's list for any
  420.                    unfreed allocations and report the number in a
  421.                    dialogue box.  So that the list is easy to read in
  422.                    the debugger, it (NewTrack) will then collate a
  423.                    list of the allocations in an array.
  424.  
  425.  
  426.  
  427.  
  428.                Uninitialised Data
  429.  
  430.                    A bug which is quite obvious as to it's source
  431.                    when it appears but is often difficult to
  432.                    reproduce is uninitialised data.  A program always
  433.                    works fine until the first day at the customer
  434.                    site when the very first thing it does is print
  435.                    two-and-a-half pages of garbage across the screen
  436.                    and dies, because you've just tried to print an
  437.                    uninitialised string.
  438.  
  439.                    As programmers, we tend to keep pretty much the
  440.                    same working environment;  under Windows or
  441.                    DesqView, I can move between my 3 apps with my
  442.                    eyes shut, because they are always in the same
  443.                    configuration (BC++, MSDOS, & Program Manager).  I
  444.                    also reboot fairly often.  This means that I have
  445.                    large expanses of zero-ed memory in my 16Mb PC,
  446.                    and uninitialised data won't show up as easily as
  447.                    on well used user's PC which is short on RAM which
  448.                    quickly becomes unzero-ed.
  449.  
  450.                    NewTrack solves this problem by always initiating
  451.                    allocated memory to garbage.  An arbitrary number
  452.                    (in fact 0x23, or '#') is used to clear any
  453.                    allocated block before it is returned to the
  454.                    application.
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.             Cavendish Software Ltd                                5
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.                Using Deleted Memory                   Just as using uninitialised allocated data can
  472.                    cause a problem, using initialised de-allocated
  473.                    memory can also be very destructive, just when you
  474.                    don't want it.  The Windows protected-mode kernel
  475.                    will stop you from using areas of memory which are
  476.                    no longer in use by the suballocation scheme, but
  477.                    it won't otherwise do anything for you.  And while
  478.                    you inadvertently carry on using this area of
  479.                    memory, it may become corrupt at any time (from
  480.                    your point of view), and if you write to it, you
  481.                    corrupt it for another piece of code.  Just as
  482.                    with uninitialised data, it's easy not to notice
  483.                    that you're using a deleted block because the
  484.                    program happens to work on your machine.
  485.  
  486.                    NewTrack can only partially solve this problem, by
  487.                    setting all the data in a block to a known garbage
  488.                    (0xFF) value immediately before calling free().
  489.                    This makes it far easier to detect (pointers
  490.                    especially).
  491.  
  492.  
  493.  
  494.  
  495.                Out of Memory
  496.  
  497.                    Because new is used in C++ much more than malloc()
  498.                    and its equivalents were in C, it is very
  499.                    inconvenient as well as time and space consuming
  500.                    to always check that the allocation succeeded.
  501.                    This is the only function of NewTrack that is also
  502.                    provided as standard in any other C++ compiler;
  503.                    the function set_new_handler() can be used to set
  504.                    a pointer to a function which is called when the
  505.                    default new function runs out of memory when
  506.                    calling malloc().
  507.  
  508.                    NewTrack handles this condition itself, and
  509.                    ignores the function set by set_new_handler().  As
  510.                    with other errors, it will notify the user with a
  511.                    dialogue box.
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.             Cavendish Software Ltd                                6
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.             How to Use NewTrack
  538.  
  539.  
  540.  
  541.  
  542.                Adding NewTrack to the build
  543.  
  544.                    NewTrack comprises of two source files; one called
  545.                    NEWTRACK.CPP which must be compiled and linked
  546.                    into every .DLL as well as the .EXE, which
  547.                    contains new versions of new and delete.  These
  548.                    call functions in the NewTrack .DLL so that
  549.                    NewTrack can share it's list of allocations; if it
  550.                    could not do this, data new'ed by one module (ie
  551.                    .DLL or .EXE) could not be delete'ed by another
  552.                    (this does not mean that tasks are allowed to free
  553.                    each other's memory).  When NewTrack allocates
  554.                    additional memory for over- and underrun checking,
  555.                    it allocates a single block and returns a pointer
  556.                    offset (by the size of the header) from that
  557.                    returned by malloc().  This pointer cannot be
  558.                    freed by any function other than the NewTrack
  559.                    version of delete, so NEWTRACK.CPP must be built
  560.                    into each and every module that makes up an
  561.                    application during it's development.
  562.  
  563.                    The .DLL is made up of a single source file called
  564.                    NEWTDLL.CPP.  The import library generated from
  565.                    this .DLL and NEWTRACK.CPP should then simply be
  566.                    added to each module.
  567.  
  568.  
  569.  
  570.  
  571.                Starting and Stopping
  572.                NewTrack
  573.  
  574.                    NewTrack has to be explicitly started and stopped
  575.                    by calling the following two functions:
  576.  
  577.  
  578.                         void NT_Initialise(void);
  579.                         void NT_Terminate(void);
  580.  
  581.                    The best place for this at the start and end of
  582.                    main() respectively.  All calls to new and delete
  583.                    will be passed through NewTrack if you have
  584.                    NewTrack linked in;  however, NewTrack does not
  585.                    run (ie no validation is performed, and no extra
  586.                    memory is allocated), except after calling
  587.                    NT_Initialise() and before calling NT_Terminate().
  588.                    If NewTrack is not running, new and delete will
  589.                    have the same effect as the default.
  590.  
  591.  
  592.  
  593.             Cavendish Software Ltd                                7
  594.  
  595.  
  596.  
  597.  
  598.  
  599.                    In order to detect memory overruns and underruns,
  600.                    NewTrack will allocate a larger amount of memory
  601.                    than asked for, fill in the known values, and
  602.                    return the pointer returned by malloc() + the size
  603.                    of the header.  This means that because NewTrack
  604.                    has added extra bytes to the pointer, the pointer
  605.                    returned by new cannot be directly returned to
  606.                    free() either by you or by delete, because it is
  607.                    no longer pointing to the start of a memory block.
  608.                    Therefore, a pointer allocated before
  609.                    NT_Terminate() cannot be freed by either a call to
  610.                    free() or by calling delete after the call to
  611.                    NT_Terminate().  Remember that this includes
  612.                    memory deallocated by a global constructor.
  613.  
  614.                    Any memory new'ed while NewTrack is running must
  615.                    also be delete'ed while NewTrack is running, and
  616.                    vice versa.  Remember that this includes automatic
  617.                    variables which are implicitly new'ed and
  618.                    delete'ed by the compiler, and memory freed by a
  619.                    global destructor; the compiler will new
  620.                    automatics where you declare them, but delete them
  621.                    after the last statement in the block, so you
  622.                    should not declare automatics in the same block as
  623.                    the NT_Initialise()/NT_Terminate() pair.  If
  624.                    necessary simply declare a block around the code
  625.                    between the functions.
  626.  
  627.  
  628.  
  629.  
  630.                Temporarily Stopping NewTrack
  631.  
  632.                    Sometimes new's and delete's are not wanted to be
  633.                    passed to NewTrack; this is true of anything which
  634.                    is to be allocated and freed when NewTrack is and
  635.                    is not running.  NewTrack includes macros which
  636.                    can temporarily disable NewTrack for the current
  637.                    module.  As described above, anything allocated
  638.                    when NewTrack is running must also be freed when
  639.                    NewTrack is running, and vice-versa.  This is also
  640.                    true of temporarily stopping NewTrack, because the
  641.                    calls to new and delete are passed on directly to
  642.                    malloc() and free().
  643.  
  644.                    There are four macros, defined in NEWTRACK.HPP:
  645.  
  646.                       NEWTRACK_ON()
  647.                       NEWTRACK_OFF()
  648.                       NEWTRACK_PUSH()
  649.                       NEWTRACK_POP()
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.             Cavendish Software Ltd                                8
  660.  
  661.  
  662.  
  663.  
  664.  
  665.                    NEWTRACK_ON() and NEWTRACK_OFF() absolutely
  666.                    disable NewTrack.  NEWTRACK_PUSH() and
  667.                    NEWTRACK_POP() save and restore the state in a
  668.                    temporary variable.  The NEWTRACK_PUSH() macro
  669.                    declares a variable in the code where it is
  670.                    called, and must therefore be called from either
  671.                    the same block as NEWTRACK_POP() or at a higher
  672.                    level; both must be called within the same
  673.                    function.
  674.  
  675.  
  676.  
  677.  
  678.                Dialogue Box
  679.  
  680.                    In order to report errors detected and to
  681.                    determine the next course of action, NewTrack uses
  682.                    the MessageBox() function to throw up a system-
  683.                    modal dialogue box with a short description of the
  684.                    error.  The box has two buttons - OK and Cancel.
  685.                    OK will allow the error to be ignored (whilst
  686.                    preventing any destructive action, such as invalid
  687.                    pointer deletion), and Cancel will cause the
  688.                    program to abort.
  689.  
  690.  
  691.  
  692.  
  693.                Debugging with NewTrack
  694.  
  695.                    As described in the previous section, when
  696.                    NewTrack discovers an error it displays a dialogue
  697.                    box.  If the user presses OK, NewTrack then calls
  698.                    INT 3, the standard method of communicating a
  699.                    breakpoint to a debugger.  The programmer can then
  700.                    trace back through the stack to the particular
  701.                    call to delete that failed, and find out why.
  702.  
  703.                    When NT_Terminate() is called, it will also call
  704.                    INT 3 after it has generated the list of unfreed
  705.                    allocations.  After the debugger has broken in for
  706.                    the first time, you should "Run" or "Go" (not a
  707.                    step or trace) to reach the second INT 3.  The
  708.                    list is pointed to in the NewTrack code by a local
  709.                    variable called blist, each of whose members is a
  710.                    pointer to a structure identifying the memory
  711.                    allocated.  Each structure contains a far void
  712.                    pointer called caller, which identifies the
  713.                    address of the call to new that allocated the
  714.                    pointer.  By using the debugger to set a break
  715.                    point at that address(es) and restarting, you can
  716.                    see where the memory was allocated from the next
  717.                    time the program breaks.  The structure also
  718.                    contains a pointer to the real address of the
  719.                    allocation (ie the pointer returned by malloc(),
  720.                    which will contain a 12-byte header), and size,
  721.                    etc.
  722.  
  723.  
  724.  
  725.             Cavendish Software Ltd                                9
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.             Pitfalls and Programming Considerations
  736.  
  737.  
  738.  
  739.  
  740.                Malloc()
  741.  
  742.                    NewTrack only recognises allocations passed though
  743.                    it's new function as valid for its delete
  744.                    function, so always make sure that allocations are
  745.                    deallocated with the corresponding function for
  746.                    the allocation.  Functions such as malloc(),
  747.                    calloc(), realloc(), etc, may only be used with
  748.                    free(); calling delete will result in an "Invalid
  749.                    Pointer Deletion" error message.  Note also that
  750.                    strdup() uses malloc(), not new.
  751.  
  752.  
  753.  
  754.  
  755.                Automatics
  756.  
  757.                    Automatic variables are implicitly new'ed by the
  758.                    compiler where they are declared, and delete'ed
  759.                    after the last statement in the block, so take
  760.                    care not to declare automatic variables in between
  761.                    the calls to NT_Initialise() and NT_Terminate() in
  762.                    the same block as the calls.
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.             Cavendish Software Ltd                               10
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.             Porting to other Environments and Compilers
  802.  
  803.                    There are several areas which could cause a
  804.                    problems when porting NewTrack, but these are
  805.                    pretty much off the top of my head, so apologies
  806.                    for any mistakes.
  807.  
  808.  
  809.  
  810.  
  811.                Memory Model
  812.  
  813.                    NewTrack has only ever been used in Borland C++
  814.                    v3.0 and v3.1 in Large memory model, under
  815.                    protected mode Windows 3.1.  The current BC++
  816.                    version is v3.1, but the only difference to BC++
  817.                    v3.0 is an additional version of new.
  818.  
  819.                    NewTrack should port easily to other memory
  820.                    models, with judicial additions of the far keyword
  821.                    for pointers in small models.
  822.  
  823.  
  824.  
  825.  
  826.                Versions of operator new()
  827.  
  828.                    Firstly, starting with Borland C++ v3.1, there are
  829.                    two versions of new - one for small (0 to 64Kb)
  830.                    allocations, and one for huge (64Kb to 4Gb)
  831.                    allocations.  It doesn't matter to NewTrack which
  832.                    is used; it handles 0 to 4Gb (theoretically - when
  833.                    I have 4Gb in my PC I'll try it!)  If your
  834.                    compiler only has one version, just exclude the
  835.                    other with conditional compilation.
  836.  
  837.  
  838.  
  839.  
  840.                Getting the callers address
  841.  
  842.                    Secondly, the caller's address is obtained by
  843.                    getting the 4-byte address from the stack as BP- 2
  844.                    - <size of arguments>.  I worked this out through
  845.                    trial and error, by tracing the assembler under
  846.                    the debugger, and looking at BP before call and at
  847.                    the first statement in operator new().  This will
  848.                    vary between memory models.
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.             Cavendish Software Ltd                               11
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.                Inline assembler                   The debugger hook (ie calling INT 3) is done by
  868.                    inline assembler; not all compiler support this,
  869.                    or may have a different syntax.  If the compiler
  870.                    does not support inline assembler, call the
  871.                    Windows function DebugBreak().  This will place
  872.                    the debugger in the assembler code of that
  873.                    function, on a RET instruction.  Simply trace
  874.                    through the RET to return to the source.  NewTrack
  875.                    uses inline assembler to prevent the inconvenience
  876.                    of trace back out of the function.
  877.  
  878.                    Under DOS, the function can be created by
  879.                    allocating a two byte area and filling it with the
  880.                    values 0xC3 0xCC (eg unsigned short fred =
  881.                    0xC3CC;).  This is the mnemonics for INT 3 in
  882.                    reverse order (Intel chips reverse the bytes when
  883.                    storing integers).  If a function pointer is
  884.                    created to point to this value, it can be called
  885.                    to create the interrupt (eg void
  886.                    (*myint03function)(void) = &fred;).
  887.  
  888.  
  889.  
  890.  
  891.                Shared libraries/DLLs
  892.  
  893.                    You must only have one copy of NEWTDLL.CPP in the
  894.                    entire executable.  This probably won't be a
  895.                    problem except where, like Windows, DLLs are
  896.                    linked into separate modules with almost all the
  897.                    qualities of a separate executable.
  898.  
  899.                    The actual requirement (which is solved for
  900.                    Windows by having NEWTDLL.CPP in a DLL) is that
  901.                    there must be a single global 'collector' or
  902.                    administrating piece of code for all allocations
  903.                    that are made, whether by the main executable or
  904.                    by another shared library or DLL.  Having a
  905.                    separate version of NEWTDLL.CPP for each library
  906.                    will mean that all allocations made by one library
  907.                    will be collected by that library and must then be
  908.                    deleted by the same library or the allocation will
  909.                    not be recognised.
  910.  
  911.                    Remember that the calls to new and delete made by
  912.                    NEWTDLL.CPP must not be validated by the NEWTDLL
  913.                    code, because the allocation and deallocation will
  914.                    become infinitely recursive.  This is achieved by
  915.                    turning off the __newtrack flag (which is what the
  916.                    NEWTRACK_XXX() macros access) in that module.
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.             Cavendish Software Ltd                               12
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.                User I/O                   You will need to put in conditional compilation to
  934.                    replace the call to MessageBox(), but little else
  935.                    is required.
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.             Cavendish Software Ltd                               13
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.             Comments, and where to find us
  1000.  
  1001.                    Please let us know what you think, even if it's
  1002.                    just to say you use it.  We'd really like to know
  1003.                    whether it's good or bad, what can be improved,
  1004.                    what works and what doesn't.  Also, if you send
  1005.                    code changes to improve it or port it to another
  1006.                    platform/compiler (for example), we'll try and put
  1007.                    them in if we have a suitable environment to
  1008.                    develop in, but no promises.
  1009.  
  1010.                    This is only one of a series of C++ tools that
  1011.                    we're working on.  Soon to arrive (but not
  1012.                    shareware) is an inter-process communication class
  1013.                    called IPC (!) which allows transparent
  1014.                    communication across any network, no matter how
  1015.                    far or wide.  Also, a portable filing system class
  1016.                    library (called FileServ) which supports data
  1017.                    dictionaries, automated file version control,
  1018.                    transparent interchange of filing systems,
  1019.                    retrieving records as of a given date and time (eg
  1020.                    the entire record that was in use at 4:23pm on 23
  1021.                    April 1992, but has since been deleted or modified
  1022.                    beyond recognition) and much more.  FileServ will
  1023.                    support many popular databases such as Paradox,
  1024.                    Btrieve (already in use), C-ISAM, and the ability
  1025.                    to easily add others.
  1026.  
  1027.                    NEWTRACK IS NOT A REGISTERABLE PRODUCT - sorry,
  1028.                    but we can make no warranties for NewTrack.  We
  1029.                    probably will no doubt maintain a list of NewTrack
  1030.                    users who send mail and tell them about new
  1031.                    versions (unless they ask otherwise), but it
  1032.                    depends on volume, so no guarantees.  The upside
  1033.                    is that there is no charge (this is completely
  1034.                    free software), and things may change in the
  1035.                    future.  On the other hand, if you feel it's a
  1036.                    useful product and/or you feel so inclined, we
  1037.                    suggest something around the UK#10 or US$15 mark
  1038.                    is about right.
  1039.  
  1040.                    Contact John Spackman on Compuserve at 100034,207,
  1041.                    on CIX as nasrudin or as
  1042.                    nasrudin@cix.compulink.co.uk, or snail mail at:
  1043.  
  1044.                        Cavendish Software Ltd
  1045.                        50 Avenue Road
  1046.                        Trowbridge
  1047.                        Wilts
  1048.                        BA14 0AQ
  1049.                        England
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.             Cavendish Software Ltd                               14
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.                    You can also ring or fax us on 0225-763598 or
  1062.                    0225-777359 respectively; international callers
  1063.                    will have to replace the leading 0 with 44.
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.             Cavendish Software Ltd                               15
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.             Copyright, Use & Copying
  1132.  
  1133.                    NewTrack is copyright to Cavendish Software
  1134.                    Limited, from 1991, and is released to the public
  1135.                    free of charge or restriction of use, except that
  1136.                    the package may not be sold in part or in whole
  1137.                    except in a compiled form as part of an executable
  1138.                    that cannot form part of another executable.
  1139.                    NewTrack may be freely distributed as source so
  1140.                    long as the entire package is given.  NewTrack may
  1141.                    be modified as required, but will remain copyright
  1142.                    of Cavendish Software Ltd, until such changes have
  1143.                    been made to render the source code and function
  1144.                    of NewTrack unrecognisable from the original.
  1145.  
  1146.                    This software is provided by Cavendish Software
  1147.                    Limited "as is'' and any express or implied
  1148.                    warranties, including, but not limited to, the
  1149.                    implied warranties of merchantability and fitness
  1150.                    for a particular purpose are disclaimed.  In no
  1151.                    event shall Cavendish Software Limited be liable
  1152.                    for any direct, indirect, incidental, special,
  1153.                    exemplary, or consequential damages (including,
  1154.                    but not limited to, procurement of substitute
  1155.                    goods or services; loss of use, data, or profits;
  1156.                    or business interruption) however caused and on
  1157.                    any theory of liability, whether in contract,
  1158.                    strict liability, or tort (including negligence or
  1159.                    otherwise) arising in any way out of the use of
  1160.                    this software, even if advised of the possibility
  1161.                    of such damage.
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.             Cavendish Software Ltd                               16